<?php

namespace Utuo;

use Think\Controller;

class WechatActivityController extends Controller {
	// 客户id
	protected $cid;
	
	// 活动id
	protected $aid;
	
	// 来源用户id
	protected $fid;
	
	// 活动标记
	protected $tag;
	
	// app id
	private $appId;
	
	// app secret
	private $appSecret;
	
	// open id
	protected $openId;
	
	// state
	private $state;
	
	// user info
	protected $userInfo;
	
	// 是否启用用户信息缓存
	protected $cacheEnabled = false;
	// 用户信息缓存时间(秒)
	protected $cacheExpires = 3600;
	// 用户信息缓存键名
	const CACHE_USER_INFO_KEY = '__wechat_user_info';
	// 缓存时间键名
	const CACHE_TIME_KEY = '__cache_time';
	
	// wechat advance instance
	private $wechatAdvance;
	
	// 是否启用网页授权跳转
	private $authEnabled = true;
	
	// 分享数据
	protected $share = array();
	
	// constructor
	public function __construct() {
		parent::__construct();
// 		if ( CONTROLLER_NAME != 'WechatVote' ) {
// 			echo "<html><meta name=\"viewport\" content=\"target-densitydpi=high-dpi\" />
// <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title></title><body><h1>系统升级中，更多精彩敬请期待。。。</h1></body></html>";
// 			die();
// 		}
// 		header("Content-Type:text/html; charset=UTF-8");
		
		$this->cid = I('cid', 0, 'intval') or $this->showError('cid不正确'.print_r($_POST,true));
		$this->aid = I('aid', 0, 'intval') or $this->showError('aid不正确');
		$this->fid = I('fid', 0, 'intval');
		$this->tag = strtolower(CONTROLLER_NAME);
		
		$wechatConfig = M('wechat')->field('id,appid,appsecret')->where('cid=%d', $this->cid)->find();
		empty($wechatConfig['appid']) && $this->showError('appid不正确');
		empty($wechatConfig['appsecret']) && $this->showError('appsecret不正确');
		$this->appId = $wechatConfig['appid'];
		$this->appSecret = $wechatConfig['appsecret'];
		$this->state = substr(md5($this->appId), 0, 16);
		$this->wechatAdvance = new WechatAdvance($this->appId, $this->appSecret);
		$this->wechatAdvance->setCacheEnabled(false);
		
		// 记录客户PV
		PVReport::report($this->cid);
		
		isset($_GET['debug']) && $this->setAuthEnabled(false);
		// 网页授权跳转
		$this->isAuthEnabled() && $this->authJump();
		
		if ( !$this->userInfo and isset( $_REQUEST['debug'] ) and $_REQUEST['debug'] == 'zhangrui.songyi') {
			$debugUid = $_REQUEST['debugUid'] or $debugUid = 0;
			$condition = array( 'cid' => $this->cid, );
			$debugUid and $condition['id'] = $debugUid;
			$vuser = M("WechatActivityUser")->where($condition)->find();
			if ( $vuser ) {
				$this->userInfo = $vuser;
				$this->setUserInfoCache();
			}
		}
		
		$this->cacheOpenId();
	}
	
	/**
	 * 设置分享内容
	 * @param unknown $config
	 * array(
	 * 	  'imgUrl' => '',
	 * 	  'link' => '',
	 *    'desc' => '',
	 *    'title' => '',
	 * )
	 */
	public function setShare( $config ) {
	    $this->share = array_merge( $this->share, $config );
	}
	
	// 缓存openid
	protected function cacheOpenId() {
		$this->openIdKey = "openId{$this->cid}";
		if ( $this->openId ) {
			session($this->openIdKey, $this->openId);
		} else {
			$this->openId = session($this->openIdKey);
		}
		session("openIdKey", $this->openIdKey); // 支付中使用
	}
	
	// 设置是否启用网页授权跳转
	protected function setAuthEnabled($enabled) {
		$this->authEnabled = !!$enabled;
	}
	
	// 获取是否启用网页授权跳转
	protected function isAuthEnabled() {
		return $this->authEnabled;
	}
	
	// 根据id获取用户信息
	protected function getUserInfo($id){
	    $condition = array(
	        'id'=>$id,
	        'cid' => $this->cid,
	        'aid'=>$this->aid,
	        'tag'=>$this->tag
	    );
	    
	   $userInfo = M('WechatActivityUser')->where($condition)->find();
	   return $userInfo;
	}
	
	/**
	 * 重构display
	 *
	 * @see \Think\Controller::display()
	 */
	protected function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '') {
		C('TMPL_PARSE_STRING.__STATIC__', __ROOT__ . '/Public/Static');
		C('TMPL_PARSE_STRING.__STYLE__', __ROOT__ . '/Public/Style/' . MODULE_NAME . '/Default');
		
		/* WECHAT JSAPI 签名包 */
		if ( $this->wechatAdvance ) {
		    $signPackage = $this->wechatAdvance->getSignPackage();
		    $this->assign("wxConfig", $signPackage);
		}
		empty($this->share) or $this->assign('share',json_encode($this->share));
		parent::display($templateFile, $charset, $contentType, $content, $prefix);
	}
	
	// 网页授权页面跳转
	protected function authJump() {
		// 获取用户信息缓存
		$this->userInfo = $this->getUserInfoCache();
		
		// 缓存不可用
		if (!$this->userInfo) {
			$state = I('state');
			if ($state == $this->state) {
				// 已经跳转后
				$code = I('code');
				$authAccess = $this->wechatAdvance->getAuthAccessToken($code);
				$this->openId = $authAccess['openid'];
				$baseAccess = $this->wechatAdvance->getBaseAccess();
				
				$this->userInfo = $this->wechatAdvance->getUserInfo($baseAccess['access_token'], $this->openId);
				empty($this->userInfo) && $this->showError('获取用户信息失败');
				
				// 更新活动微信用户数据
				$this->handleActivityUserInfo();
				
				// 更新总体微信用户数据
				$this->handleWechatUserInfo();
				
				// 如果用户已经关注，则缓存用户信息，没有关注，则不缓存，以便及时监控用户是否关注
				if ($this->userInfo['subscribe']) {
					$this->setUserInfoCache();
				}
			} else {
				// 跳转
				$redirectUrl = $this->wechatAdvance->getAuthRedirectUrl($this->getCurrentUrl(), 0, $this->state);
				redirect($redirectUrl);
			}
		}
	}
	
	// 更新微信活动用户数据
	protected function handleActivityUserInfo() {
		$m = M('WechatActivityUser');
		$condition = array (
				'cid' => $this->cid,
				'aid' => $this->aid,
				'tag' => $this->tag,
				'openid' => $this->openId 
		);
		// 是否已经存在，不存在则添加，存在则更新
		$user = $m->where($condition)->find();
		
		if (empty($user)) {
			// 添加
			$data = array_merge($condition, $this->userInfo);
			$data['fid'] = $this->fid;
			$data['create_time'] = time();
			$userId = $m->add($data);
			
			if ($userId) {
				// 把用户id加入到用户信息中
				$this->userInfo = $data;
				$this->userInfo['id'] = $userId;
				// 处理用户关系树
				$tree = $userId;
				// 当来源用户id不等于0且不等于当前用户id时，取出来源用户的关系树
				if ($this->fid > 0 && $this->fid != $userId) {
					// 判断来源用户是否存在
					$fromUserTree = M("WechatActivityUserTree")->where('uid=%d', $this->fid)->getField("tree");
					empty($fromUserTree) or $tree = $tree . ',' . $fromUserTree;
				}
				M('WechatActivityUserTree')->add(array (
						'cid' => $this->cid,
						'uid' => $userId,
						'tree' => $tree 
				));
			}
		} else {
			// 更新
			$this->userInfo = array_merge($user, $this->userInfo);
			$m->save($this->userInfo);
		}
	}
	
	// 更新微信总体用户数据
	protected function handleWechatUserInfo() {
		$m = M('WechatUser');
		$user = $m->where(array (
				'cid' => $this->cid,
				'openId' => $this->openId 
		))->find();
		
		// 用户是否存在，不存在则添加，存在则更新
		if (empty($user)) {
			// 添加用户
			$data = array (
					'mid' => $this->fid,
					'cid' => $this->cid,
					'openId' => $this->openId,
					'face' => $this->userInfo['headimgurl'],
					'nickname' => $this->userInfo['nickname'],
					'createTime' => time(),
					'subscribeTime' => $this->userInfo['subscribe_time'],
					'subscribe' => $this->userInfo['subscribe'] 
			);
			$userId = $m->add($data);
			if ($userId) {
				// 当前用户树
				$tree = $userId;
				// 如果是新增用户
				// 是否存在上级用户
				if ($this->fid) {
					$father = M('WechatUser u')->join('LEFT JOIN __DISTRIBUTION_SHOP_USER_TREE__ t ON u.id=t.uid')->where('u.id=%d', $this->fid)->field("u.*, t.tree, SUBSTRING_INDEX(t.tree,',',-1) AS topId")->find();
					if ($father) {
						// 如果存在师傅，师傅的徒弟数+1
						M('WechatUser')->where("id=%d", $this->fid)->setInc("sonCount", 1);
						// 所有的上级用户的下级用户数+1
						M('WechatUser')->where(array (
								'id' => array (
										'in',
										$father['tree'] 
								) 
						))->setInc("subCount", 1);
						
						// 补充当前用户树
						$tree .= ',' . $father['tree'];
						
						$accessToken = $this->wechatAdvance->getBaseAccess();
						// 向顶级用户发模板消息
						$topUser = M('WechatUser')->field("subCount,openId")->find($father['topId']);
						$this->sendAddMsg(array (
								'newId' => $userId,
								'subCount' => $topUser['subCount'] 
						), $accessToken['access_token'], $topUser['openId']);
						// 向上级用户发模板消息
						if ($this->fid != $father['topId']) {
							$this->sendAddMsg(array (
									'newId' => $userId,
									'subCount' => $father['subCount'] 
							), $accessToken['access_token'], $father['openId']);
						}
					}
				}
				
				// 保存关系树
				M("DistributionShopUserTree")->add(array (
						'uid' => $userId,
						'cid' => $this->cid,
						'tree' => $tree 
				));
			}
		} else {
			// 更新用户
			$data = array (
					'lastLoginTime' => time(),
					'lastLoginIp' => get_client_ip(),
					'loginCount' => $user['loginCount'] 
			);
			if ($this->userInfo['subscribe' == 1]) {
				$data['nickname'] = $this->userInfo['nickname'];
				$data['face'] = $this->userInfo['headimgurl'];
				$data['subscribe'] = 1;
			}
			M('WechatUser')->where("id=%d", $user['id'])->save($data);
		}
	}
	
	/**
	 * 发送有用户加入的模板消息
	 * 
	 * @param array $param array(
	 *        newId,subCount
	 *        )
	 */
	protected function sendAddMsg($param, $accessToken, $openId) {
		$templateId = "OtEPSHE5NbL6YHT9v4ElTmsbvb6LTq5I2VRLb7lyAcs";
		$data = array (
				'first' => array (
						'value' => "恭喜，你有新的朋友加入！",
						'color' => '#0000ee' 
				),
				'infotitle' => array (
						'value' => "您有一个新的朋友加入",
						'color' => "#ee0000" 
				),
				'infoId' => array (
						'value' => str_pad($param['newId'], 6, '0', STR_PAD_LEFT),
						'color' => '#ee0000' 
				),
				'statusType' => array (
						'value' => '会员总数',
						'color' => '#000000' 
				),
				'status' => array (
						'value' => '共有会员' . $param['subCount'] . '位',
						'color' => '#ee0000' 
				),
				'remark' => array (
						'value' => '继续加油，邀请更多的朋友们加入吧~~',
						'color' => '#999999' 
				) 
		);
		$result = $this->wechatAdvance->sendTemplateMessage($accessToken, $openId, $templateId, $data);
		return $result;
	}
	
	// 设置用户缓存信息
	protected function setUserInfoCache() {
		// 是否开启了缓存
		if ($this->cacheEnabled && !empty($this->userInfo)) {
			$this->userInfo[self::CACHE_TIME_KEY] = time();
			session(self::CACHE_USER_INFO_KEY, $this->userInfo);
		}
	}
	
	// 获取用户缓存信息
	protected function getUserInfoCache() {
		// 没有开启缓存，返回false
		if (!$this->cacheEnabled) {
			return false;
		}
		$userInfoCache = session(self::CACHE_USER_INFO_KEY);
		// 缓存不存在，或者缓存已经过期，返回false
		if (empty($userInfoCache) || empty($userInfoCache[self::CACHE_TIME_KEY]) || (time() - $userInfoCache[self::CACHE_TIME_KEY] > $this->cacheExpires)) {
			return false;
		}
		// 返回缓存信息
		return $userInfoCache;
	}
	
	/**
	 * 当前URL
	 *
	 * @param 修正参数，如果参数值指定为null，则删除此参数
	 */
	protected function getCurrentUrl($fixParams = array()) {
		$params = array_merge($_GET, $fixParams);
		unset($params['code']);
		unset($params['state']);
		$args = '';
		foreach ( $params as $k => $v ) {
			$args[] = "{$k}={$v}";
		}
		$args = join('&', $args);
		$url = U(sprintf('%s/%s/%s', MODULE_NAME, CONTROLLER_NAME, ACTION_NAME), '', true, true).($args ? "?".$args : '');
		return $url;
	}
	
	/**
	 * 组装URL
	 *
	 * @param 参数
	 */
	protected function getFullUrl($params = array(), $action = ACTION_NAME, $controller = CONTROLLER_NAME, $module = MODULE_NAME) {
		$url = U(sprintf('%s/%s/%s', $module, $controller, $action), $params, true, true);
		return $url;
	}
	
	// show error msg & exit
	protected function showError($msg) {
		IS_AJAX ? $this->ajaxError($msg) : exit($msg);
	}
	
	// ajax error
	protected function ajaxError($msg = '请求错误', $data = null) {
		$this->ajaxReturn(array (
				'state' => 0,
				'msg' => $msg,
				'data' => $data 
		));
		exit();
	}
	
	// ajax success
	protected function ajaxSuccess($msg = "请求成功", $data = null) {
		$this->ajaxReturn(array (
				'state' => 1,
				'msg' => $msg,
				'data' => $data 
		));
		exit();
	}
	
	/**
	 * 读写分离开关
	 * @param unknown $status
	 */
	protected function rwSeparate( $status ) {
		static $rwStatus = array();
		if ( $status ) {
			$rwStatus[] = 1;
			C('DB_HOST', SAE_MYSQL_HOST_M.','.SAE_MYSQL_HOST_S);
		} else {
			$last2 = $rwStatus[count($rwStatus)-2];
			if ( !$last2 ) {
				C('DB_HOST', SAE_MYSQL_HOST_M);
			}
			array_pop($rwStatus);
		}
	}
}